﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BaseEntity : MonoBehaviour
{
    public delegate void DeathDelegate(EntityType entityType);

    public DeathDelegate deathEvent;
    
    [SerializeField, Header("状态")]
    public EntityStatusEnum _status;
    
    [Header("基本属性")]
    [SerializeField] public int _hp = 0;
    [SerializeField] public int _hp_max = 0;
    [SerializeField] public int _ap = 0;
    [SerializeField] public int _ap_max = 0;
    [SerializeField] public int _mp = 0;
    [SerializeField] public int _mp_max = 0;
    [SerializeField] public int _fp = 0;
    [SerializeField] public int _fp_max = 0;
    [SerializeField] public int _money = 0; 
    
    [SerializeField] public int _shield = 0;

    [SerializeField] public bool isDead = false;

    [SerializeField] private Dictionary<EntityStatusEnum, List<Action>> buffMap = new Dictionary<EntityStatusEnum, List<Action>>();
    
    [Header("卡牌属性")] 
    [SerializeField] public bool isHoldingCard;
    
    protected CardManager _cardManager;
    
    public delegate void AttackListener();

    public AttackListener attackListener;
    
    protected bool _isImmuneAttack = false;
    protected bool _isDestroyable = true;

    public bool is_need_play_next_animation = false;
    public AttackType next_animation_type;

    private Queue triggerQueue;
    public GameObject beater;

    protected Action? overWatchAction;
    
    #region Custome Functions
    
    
    public virtual void FlushStatus() { }

    public virtual void SetOverWatch(Action action)
    {
        overWatchAction = action; 
    }

    public virtual void RemoveOverWatch()
    {
        overWatchAction = null;
    }

    public virtual void APChange(int changeVal)
    {
        _ap += changeVal;
    }
    
    public virtual void FPChange(int changeVal)
    {
        _fp += changeVal;
    }

    public virtual void ExecuteCardEffectListener()
    {
        attackListener?.Invoke();   
    }
    
    public virtual void DealWithCardEffect(GameObject receiver, CardScriptable cardData, Vector3 targetPosition)
    {
        this.is_need_play_next_animation = true;
        this.next_animation_type = cardData.attackType;
        
        receiver.GetComponent<BaseEntity>().beater = this.gameObject;
        
        Debug.Log($"目前使用的卡 {cardData.name}");

        // TODO 然后处理动画效果，处理完之后才开始执行伤害计算
        // TODO 这里有办法将效果传入到这个动画的回调吗
        // 又或者 回调是触发一个使用函数

        attackListener = () =>
        {
            if (cardData.fxPrefab)
            {
                GameObject fxObject = GameObject.Instantiate(cardData.fxPrefab, this.gameObject.transform.position, Quaternion.identity);
//        fxObject.transform.SetParent(GameObject.FindGameObjectWithTag(StaticDataManager.PLAYER_TAG).transform);
                fxObject.GetComponent<Projectile>().SetTargetPoint(receiver.transform.position);            
            } 
        
            BattleResolver.ExecuteCardAction(cardData.nextActions,
                caller: this.gameObject,
                receiver: receiver,
                targetPosition: targetPosition);
        };
    }
    
    public virtual void DealWithOverWatch(GameObject other)
    {
        Debug.Log("有东西进来了");
        other.GetComponent<MovableEntity>().moveSpeed = 0f;
        BattleResolver.ExecuteCardAction(new [] {overWatchAction}, gameObject, other, Vector3.zero);
        other.GetComponent<MovableEntity>().moveSpeed = 2.8f;
        RemoveOverWatch();
    }

    public virtual void AddBuff(Action action)
    {
        Debug.Log($"添加了BUFF {action}");
        if (!buffMap.ContainsKey(action.effectTriggerType))
        {
            buffMap[action.effectTriggerType] = new List<Action>();
        }
        
        buffMap[action.effectTriggerType].Add(action);
    }

    public virtual void ExecuteBuffQueue(bool isBefore)
    {    
        EntityStatusEnum currentStatus;
        if (!buffMap.ContainsKey(_status))
        {
            return;
        }
        
        currentStatus = _status;

        Debug.Log($"反击 :: 当前挂在的触发事件个数有 {buffMap[currentStatus].Count}");
        
        for (int i = 0; i < buffMap[currentStatus].Count; i++)
        {
            var action = buffMap[currentStatus][i];

            // TODO 检查触发对象
            if (action.targetType == TargetType.Target)
            {
                Debug.Log("反击 :: 是时候获取攻击者的身份了");
                // TODO 需要获得被攻击者的信息
                action.receiver = beater;
                action.caller = gameObject;
            }
            
            BattleResolver.ExecuteCardAction(new [] {action}, action.caller, action.receiver, Vector3.zero);
            action.remainCount -= 1;
        }
    }

    public virtual void FlushBuffs()
    {
        
    }
    
    public CardManager GetCardManager()
    {
        return _cardManager;
    }
    
    public virtual void DealDamage(int damage)
    {
        if (_isImmuneAttack) return;
        
        if (_shield > 0)
        {
            if (damage > _shield)
            {
                damage -= _shield;
                _shield = 0;
            }
            else
            {
                _shield -= damage;
                damage = 0;
            }
        }

        Debug.Log($"伤害 {damage}");
        
        _hp -= damage;
        
    }

    protected void CheckHP()
    {
        if (!_isDestroyable) return;
        
        _status = _hp <= 0 ? EntityStatusEnum.Destroy : EntityStatusEnum.Idle;
    }

    public void DestroySelf()
    {
        Destroy(gameObject);
    }

    protected virtual void TurnStart()
    {
        
    }

    public virtual void TurnEnd()
    {
        
    }
    
    #endregion

    #region Events

    private void Start()
    {
        _status = EntityStatusEnum.Idle;
    }

    private void Update()
    {
        switch (_status)
        {
            case EntityStatusEnum.Initialize:
                break;
            case EntityStatusEnum.Idle:
                break;
            case EntityStatusEnum.Thinking:
                break;
            case EntityStatusEnum.Moving:
                break;
            case EntityStatusEnum.Attack:
                break;
            case EntityStatusEnum.Guard:
                break;
            case EntityStatusEnum.OverWatching:
                break;
            case EntityStatusEnum.Destroy:
                DestroySelf();
                break;
            case EntityStatusEnum.Beaten:
                CheckHP();
                break;
            case EntityStatusEnum.TurnStart:
                TurnStart();
                break;
            case EntityStatusEnum.TurnEnd:
                TurnEnd();
                break;
            default:
                Debug.LogWarning($"{nameof(gameObject)} 出现意外的状态");
                break;
        }
    }

    public virtual void StartTurn()
    {
        _status = EntityStatusEnum.TurnStart;
        if (!this.gameObject.CompareTag(StaticDataManager.PLAYER_TAG)) return;
        
        GameObject selectGrid = GameObject.FindGameObjectWithTag(StaticDataManager.SELECT_GRID_TAG);
        selectGrid.transform.localScale = Vector3.one;
        selectGrid.transform.position = GameObject.FindGameObjectWithTag(StaticDataManager.PLAYER_TAG).transform.position;
    }

    public virtual void EndTurn()
    {
        if (!this.gameObject.CompareTag(StaticDataManager.PLAYER_TAG)) return;
        
        GameObject selectGrid = GameObject.FindGameObjectWithTag(StaticDataManager.SELECT_GRID_TAG);
        selectGrid.transform.localScale = Vector3.zero;

        _status = EntityStatusEnum.TurnEnd;
    }
    #endregion

    private void DiscardCard()
    {
        
    }
}
